#include<iostream>
#include<random>
#include<sstream>
#include<iomanip>
#include<atomic>
/*
UUID(Universally Unique Identifier), 也叫通⽤唯⼀识别码，通常由32位16进制数字字符组成。
UUID的标准型式包含32个16进制数字字符，以连字号分为五段，形式为8-4-4-4-12的32个字符，如：
550e8400-e29b-41d4-a716-446655440000。
在这⾥，uuid⽣成，我们采⽤⽣成8个随机数字，加上8字节序号，共16字节数组⽣成32位16进制字符
的组合形式来确保全局唯⼀的同时能够根据序号来分辨数据
*/

static std::string uuid()
{
    std::random_device rd;
    std::mt19937_64 gernator(rd());
    // 需要8个0 到255之间的数字 要限定数字区间
    std::uniform_int_distribution<int> distribution(0, 255);
    // 将生成的随机数转换位16进制数字字符
    std::stringstream ss;
    for (int i = 0; i < 8; i++)
    {
        // 可能出现小于16 单字符情况 所以设置位宽2 高位填充0
        ss << std::setw(2) << std::setfill('0') << std::hex << distribution(gernator);
        // 8-4-4
        if (i == 3 || i == 5 || i == 7)
            ss << "-";
    }
    static std::atomic<size_t> seq(1); // 定义一个原子类型整数序列号 初始化为1
    size_t num = seq.fetch_add(1);     // 前置++
    for (int i = 7; i >= 0; i--)
    {
        //   & 0000000000001111111111111
        ss << std::setw(2) << std::setfill('0') << std::hex << ((num >> i * 8) & 0xff);
        // 8-4-4-   4-12
        if (i == 6)
            ss << "-";
    }
    return ss.str();
}

int main()
{
    // std::random_device rd;
    // // size_t num = rd();       生成一个机器随机数 效率比较低
    // // //用机器随机数作为梅森旋转的种子
    // //梅森旋转生成 0 ~ 2^19937 间的伪随机数 输入种子
    // std::mt19937_64 gernator(rd());         
    // //需要8个0 到255之间的数字 要限定数字区间
    // std::uniform_int_distribution<int> distribution(0, 255);
    // //将生成的随机数转换位16进制数字字符
    // std::stringstream ss;
    // for(int i = 0; i < 8; i ++)
    // {
    //     // 可能出现小于16 单字符情况 所以设置位宽2 高位填充0
    //     ss << std::setw(2) << std::setfill('0') << std::hex << distribution(gernator);
    //     // 8-4-4
    //     if(i == 3 || i == 5 || i ==7)
    //         ss << "-";                  
    // }
    // static std::atomic<size_t> seq(1); //定义一个原子类型整数序列号 初始化为1
    // size_t num = seq.fetch_add(1);     //前置++
    // for(int i = 7; i >= 0; i --)
    // {
    //     //   & 0000000000001111111111111
    //     ss << std::setw(2) << std::setfill('0') << std::hex << ((num >> i * 8) & 0xff);
    //     // 8-4-4-   4-12
    //     if(i == 6)
    //         ss << "-";                  
    // }
    for(int i = 0; i < 20; i ++)
    std::cout << uuid() << std::endl;
    return 0;
}